package com.googlecode.bicyclon.location;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;

/**
 * Class that handles the location updates from GPS.
 * @author Johan Ek
 *
 */
public class LocationHandler
{
    private transient LocationManager mLocationManager;
    private long mRefreshTime = 3000;
    private float mRefreshDistance = 5;
    private transient LocationListener mListener;
    private transient Location mLocation = null;

    /**
     * Injecter method for setting a LocationManager
     * @param locationManager The LocationManager to inject
     */
    public void setLocationManager(final LocationManager locationManager)
    {
        mLocationManager = locationManager;
    }

    /**
     * Set the time for how often the GPS-listener should update
     * @param refreshTime The refresh time in milliseconds
     */
    public void setRefreshTime(long refreshTime)
    {
        mRefreshTime = refreshTime;
    }

    /**
     * Set the distance, in meters, for when the GPS-listener should update
     * @param refreshDistance the distance in meters
     */
    public void setRefreshDistance(float refreshDistance)
    {
        mRefreshDistance = refreshDistance;
    }

    /**
     * Get the locationlistener, if none is instantiated, the default one will be used.
     * @return the location listener
     */
    private LocationListener getLocationListener()
    {
        if (mListener == null)
        {
            mListener = new MyLocationListener();
        }

        return mListener;
    }

    /**
     * Starts the listening for GPS-updates
     */
    public void startSniffing()
    {
        final String provider = LocationManager.GPS_PROVIDER;
        mLocationManager.requestLocationUpdates(provider,
                mRefreshTime,
                mRefreshDistance,
                getLocationListener());

    }


    /**
     * Stops the listening, by removing the listener.
     */
    public void stopSniffing()
    {
        mLocationManager.removeUpdates(getLocationListener());
    }

    /**
     * Update the location, used by the listener class
     *
     * @param location
     *        the Location to update
     */
    private void updateLocation(final Location location)
    {
        mLocation = location;
    }

    /**
     *
     * @return the current location or <code>null</code> if no location was set
     */
    public Location getCurrentLocation()
    {
        return mLocation;
    }

    private class MyLocationListener implements LocationListener
    {

        /**
         * {@inheritDoc}
         */
        public void onLocationChanged(final Location location)
        {
            updateLocation(location);
        }


        /**
         * {@inheritDoc}
         */
        public void onProviderDisabled(final String bla)
        {
            updateLocation(null);
        }


        /**
         * {@inheritDoc}
         */
        public void onProviderEnabled(final String provider)
        {
            // Do nothing
        }

        /**
         * {@inheritDoc}
         */
        public void onStatusChanged(final String provider, final int status, final Bundle extras)
        {
            if (status == LocationProvider.TEMPORARILY_UNAVAILABLE)
            {
                updateLocation(null);
            }
        }
    }
}
